﻿using System;

namespace Chowpoo.Util
{
    public static class SecurityDeal
    {
        /// <summary>
        /// string类型 sample: key=checkStr(Request["key"],"");
        /// </summary>
        public static string CheckStr(this object source, string defvalue)
        {
            if (source != null && source.ToString() != "")
                defvalue = source.ToString();
            return defvalue;
        }
        /// <summary>
        /// int类型 sample:pn=checkInt(Request["pn"],1);
        /// </summary>
        public static int CheckInt(this object source, int defvalue)
        {
            int defvalue2 = 0;
            if (source == null || source.ToString() == "") return defvalue;
            if (!int.TryParse(source.ToString(), out defvalue2)) defvalue2 = defvalue;
            return defvalue2;
        }
        /// <summary>
        /// byte类型
        /// </summary>
        public static byte CheckByte(this object source, byte defvalue)
        {
            byte defvalue2 = 0;
            if (source == null || source.ToString() == "") return defvalue;
            if (!byte.TryParse(source.ToString(), out defvalue2)) defvalue2 = defvalue;
            return defvalue2;
        }
        /// <summary>
        /// short类型
        /// </summary>
        public static short CheckShort(this object source, short defvalue)
        {
            short defvalue2 = 0;
            if (source == null || source.ToString() == "") return defvalue;
            if (!short.TryParse(source.ToString(), out defvalue2)) defvalue2 = defvalue;
            return defvalue2;
        }
        /// <summary>
        /// datetime类型
        /// </summary>
        public static DateTime CheckDatetime(this object source, DateTime defvalue)
        {
            DateTime defvalue2 = DateTime.Now;
            if (source == null || source.ToString() == "") return defvalue;
            if (!DateTime.TryParse(source.ToString(), out defvalue2)) defvalue2 = defvalue;
            return defvalue2;
        }

        /// <summary>
        /// datetime类型
        /// </summary>
        public static DateTime? CheckNoDatetime(this object source)
        {
            DateTime defvalue2;
            if (source == null || source.ToString() == "") return null;
            if (!DateTime.TryParse(source.ToString(), out defvalue2)) return null;
            return defvalue2;
        }

        /// <summary>
        /// decimal类型
        /// </summary>
        public static decimal CheckDecimal(this object source, decimal defvalue)
        {
            decimal defvalue2 = 1;
            if (source == null || source.ToString() == "") return defvalue;
            if (!decimal.TryParse(source.ToString(), out defvalue2)) defvalue2 = defvalue;
            return defvalue2;
        }

        /// <summary>
        /// decimal类型
        /// </summary>
        public static double CheckDouble(this object source, double defvalue)
        {
            double defvalue2;
            if (source == null || source.ToString() == "") return defvalue;
            if (!double.TryParse(source.ToString(), out defvalue2)) defvalue2 = defvalue;
            return defvalue2;
        }
        /// <summary>
        /// 常见值类型转换
        /// </summary>
        public static T CheckStruct<T>(this object source, T defvalue) where T : struct
        {
            T value = default(T);
            try
            {
                value = (T)Convert.ChangeType(source, typeof(T));
            }
            catch (Exception ex)
            {
                value = defvalue;
            }
            return value;
        }
        /// <summary>
        /// bool类型
        /// </summary>
        public static bool CheckBool(this object source, bool defvalue)
        {
            bool defvalue2 = false;
            if (source == null || source.ToString() == "") return defvalue;
            if (!bool.TryParse(source.ToString(), out defvalue2)) defvalue2 = defvalue;
            return defvalue2;
        }
        /// <summary>
        /// 检查除数不能为0，如果为0则返回1
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static double ChkZero(this double source)
        {
            return ChkZero(source, 1);
        }
        /// <summary>
        /// 检查除数不能为0,如果为0返回指定值
        /// </summary>
        /// <param name="source"></param>
        /// <param name="defvalue"></param>
        /// <returns></returns>
        public static double ChkZero(this double source, double defvalue)
        {
            if (source == 0)
                return defvalue;
            return source;
        }

        /// <summary>
        /// 检查除数不能为0，如果为0则返回1
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static int ChkZero(this int source)
        {
            return ChkZero(source, 1);
        }
        /// <summary>
        /// 检查除数不能为0,如果为0返回指定值
        /// </summary>
        /// <param name="source"></param>
        /// <param name="defvalue"></param>
        /// <returns></returns>
        public static int ChkZero(this int source, int defvalue)
        {
            if (source == 0)
                return defvalue;
            return source;
        }

        /// <summary>
        /// 四舍五入double对象 
        /// </summary>
        /// <param name="source"></param>
        /// <param name="num">小数保留位数</param>
        /// <returns></returns>
        public static double Round(this double source, int num)
        {
            return Math.Round(source, num);
        }

        /// <summary>
        /// 作除法运算 保留3位小数位
        /// </summary>
        /// <param name="source"></param>
        /// <param name="divisor"></param>
        /// <returns></returns>
        public static double Division(this double source, double divisor)
        {
            return Math.Round(source / (divisor == 0 ? 1 : divisor), 3);
        }

        /// <summary>
        /// 作除法运算 返回整数
        /// </summary>
        /// <param name="source"></param>
        /// <param name="divisor"></param>
        /// <returns></returns>
        public static int Division(this int source, int divisor)
        {
            return source / (divisor == 0 ? 1 : divisor);
        }

        /// <summary>
        /// 作除法运算 保留指定小数位 返回double类型
        /// </summary>
        /// <param name="source"></param>
        /// <param name="divisor"></param>
        /// <param name="decNum"></param>
        /// <returns></returns>
        public static double Division(this int source, object divisor, byte decNum)
        {
            double s2 = divisor.CheckDouble(1);
            return Math.Round(source / (s2 == 0 ? 1 : s2), decNum);
        }

        /// <summary>
        /// 作除法运算返回2位有效百分比
        /// </summary>
        /// <param name="source"></param>
        /// <param name="divisor"></param>
        /// <returns></returns>
        public static string DivisionStr(this int source, object divisor)
        {
            var re = Division(source, divisor, 2);
            return Math.Round(re, 2) * 100 + "%";
        }


        /// <summary>
        /// 作除法运算 保留指定小数位 并在结果后添加指定的"0"个数 返回double类型
        /// </summary>
        /// <param name="source"></param>
        /// <param name="divisor"></param>
        /// <param name="decNum"></param>
        /// <param name="mulNum"></param>
        /// <returns></returns>
        public static double Division(this int source, object divisor, byte decNum, byte mulNum)
        {
            double s2 = divisor.CheckDouble(1);
            mulNum = mulNum > 9 ? (byte)9 : mulNum;
            int num = int.Parse("1".PadRight(mulNum + 1, '0'));
            return Math.Round(source / (s2 == 0 ? 1 : s2) * num, decNum - mulNum);
        }

        /// <summary>
        /// 作除法运算 保留指定小数位 返回double类型
        /// </summary>
        /// <param name="source"></param>
        /// <param name="divisor"></param>
        /// <param name="decNum"></param>
        /// <returns></returns>
        public static double Division(this double source, object divisor, byte decNum)
        {
            double s2 = divisor.CheckDouble(1);
            return Math.Round(source / (s2 == 0 ? 1 : s2), decNum);
        }
        /// <summary>
        /// 求比率 
        /// </summary>
        public static double Rate(this double source, double rateObj)
        {
            return Math.Round((source - rateObj) / (rateObj == 0 ? 1 : rateObj), 3);
        }

        /// <summary>
        /// 求比率 
        /// </summary>
        public static double Rate(this double source, double rateObj, int decNum)
        {
            var result = (source - rateObj) / (rateObj == 0 ? 1 : rateObj);
            return Math.Round(result, decNum);
        }

        /// <summary>
        /// 求比率 
        /// </summary>
        public static double Rate(this int source, int rateObj)
        {
            return Math.Round((source - rateObj) * 1.0 / (rateObj == 0 ? 1 : rateObj), 3);
        }

        /// <summary>
        /// 求比率
        /// </summary>
        public static double Rate(this int source, int rateObj, int decNum)
        {
            var result = (source - rateObj) * 1.0 / (rateObj == 0 ? 1 : rateObj);
            return Math.Round(result, decNum);
        }



        /// <summary>
        /// 求比率 返回增加字符串百分数
        /// </summary>
        public static string RateStr(this double source, double rateObj)
        {
            var result = (source - rateObj) / (rateObj == 0 ? 1 : rateObj);
            return (result > 0 ? "+" : "") + Math.Round(result, 3) * 100 + "%";
        }

        /// <summary>
        /// 求比率 返回增加字符串百分数
        /// </summary>
        public static string RateStr(this double source, double rateObj, int decNum)
        {
            var result = (source - rateObj) / (rateObj == 0 ? 1 : rateObj);
            return (result > 0 ? "+" : "") + Math.Round(result, decNum) * 100 + "%";
        }

        /// <summary>
        /// 求比率 返回增加字符串百分数
        /// </summary>
        public static string RateStr(this int source, int rateObj)
        {
            var result = (source - rateObj) * 1.0 / (rateObj == 0 ? 1 : rateObj);
            return (result > 0 ? "+" : "") + Math.Round(result, 3) * 100 + "%";
        }

        /// <summary>
        /// 求比率 返回增加字符串百分数
        /// </summary>
        public static string RateStr(this float source, float rateObj)
        {
            var result = (source - rateObj) / (rateObj == 0 ? 1 : rateObj);
            return (result > 0 ? "+" : "") + Math.Round(result, 3) * 100 + "%";
        }

        /// <summary>
        /// 求比率 返回增加字符串百分数
        /// </summary>
        public static string RateStr(this int source, int rateObj, int decNum)
        {
            var result = (source - rateObj) * 1.0 / (rateObj == 0 ? 1 : rateObj);
            return (result > 0 ? "+" : "") + Math.Round(result, decNum) * 100 + "%";
        }

        /// <summary>
        /// 检查日期格式是否合法 不合法则返回昨天的日期 输出格式yyyy-MM-dd
        /// </summary>
        public static string CheckDate(this string sourceDate)
        {
            return sourceDate.CheckDate(-1);
        }

        /// <summary>
        /// 检查日期格式是否合法 不合法则返回当前日期指定累加天数日期形式
        /// </summary>
        public static string CheckDate(this string sourceDate, short pos)
        {
            DateTime dt;
            if (!DateTime.TryParse(sourceDate, out dt))
                return DateTime.Now.AddDays(pos).ToString();
            return dt.ToString("yyyy-MM-dd");
        }

        /// <summary>
        /// 检查月格式是否合法 不合法则返回当月 输出格式yyyy-MM
        /// </summary>
        public static string CheckMonth(this string sourceMonth)
        {
            return sourceMonth.CheckMonth(0);
        }

        /// <summary>
        /// 检查月格式是否合法 不合法则返回当前月指定累加月数  输出格式yyyy-MM
        /// </summary>
        public static string CheckMonth(this string sourceMonth, short pos)
        {
            DateTime dt;
            if (!DateTime.TryParse(sourceMonth, out dt))
                return DateTime.Now.AddMonths(pos).ToString();
            return dt.ToString("yyyy-MM");
        }

        /// <summary>
        /// 转换成百分号表示
        /// 如0.2=>+20%
        /// </summary>
        /// <param name="target"></param>
        /// <returns></returns>
        public static string Covert2Persan(this double target)
        {
            if (target == 0)
                return "-";
            return (target > 0 ? "+" : "") + Math.Round(target, 2) * 100 + "%";
        }
    }
}